package com.rf.richfitwheel.workflow.cmd;


import com.rf.richfitwheel.common.exception.BusinessException;
import com.rf.richfitwheel.common.utils.UuidUtil;
import com.rf.richfitwheel.workflow.conf.ApplicationContextRegister;
import com.rf.richfitwheel.workflow.model.WfProcessTransfer;
import com.rf.richfitwheel.workflow.service.WfProcessTransferService;
import lombok.Data;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.HistoricTaskInstanceQueryImpl;
import org.activiti.engine.impl.cmd.AddCommentCmd;
import org.activiti.engine.impl.cmd.GetDeploymentProcessDefinitionCmd;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.*;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.impl.variable.VariableType;
import org.activiti.engine.impl.variable.VariableTypes;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

/**
 * 致力于改造成一个可以分支退回主线的cmd
 * 思路 ： 根据
 * 1.主线任务 主线多人任务
 * 2.主线到分支的 单人任务 多人任务
 * 3.分支到分支的单人任务 多人任务
 * 4.分支到分支到分支 单人任务 多人任务
 * 观察ACT_RU_EXECUTION 各个字段的变化情况 总结规律
 * 退回时删除目标节点发出的所有在办任务和执行对象 和多人任务的流程变量
 * 并生成目标节点的任务和执行对象及父执行对象
 */
@Data
public class RollbackTaskCmd2 implements Command<Object> {

    private WfProcessTransferService wfProcessTransferService;

    private String nowTaskId;
    private String targetActId;
    private String deleteReason = "jump";
    private String approveMessage;
    private String approveAdvice;
    private Map<String, Object> variables = new HashMap<>();//变量

    public RollbackTaskCmd2(WfProcessTransferService wfProcessTransferService, String nowTaskId, String targetActId, String deleteReason, String approveMessage, String approveAdvice, Map<String, Object> variables) {
        this.wfProcessTransferService = wfProcessTransferService;
        this.nowTaskId = nowTaskId;
        this.targetActId = targetActId;
        this.deleteReason = deleteReason;
        this.approveMessage = approveMessage;
        this.approveAdvice = approveAdvice;
        this.variables = variables;
    }

    @Override
    public Object execute(CommandContext commandContext) {
        //获取当前任务
        TaskEntity taskEntity = commandContext.getTaskEntityManager().findTaskById(nowTaskId);
        //获取流程定义信息
        ProcessDefinitionEntity processDefinitionEntity = new GetDeploymentProcessDefinitionCmd(taskEntity.getProcessDefinitionId())
                .execute(Context.getCommandContext());
        ActivityImpl nowActivity = processDefinitionEntity.findActivity(taskEntity.getTaskDefinitionKey());
        String taskType = this.getTaskType(nowActivity);
        //获取该流程实例所有批转记录
        List<WfProcessTransfer> allFromProcInstId = wfProcessTransferService.getListByProcInstIdOrderByCreateDateAsc(taskEntity.getProcessInstanceId());
        //获取目标节点最近的一次批转记录
        List<WfProcessTransfer> nearFromTarget = wfProcessTransferService.getListByProcInstIdAndActIdOrderByCreateDateDesc(taskEntity.getProcessInstanceId(), targetActId);
        if (nearFromTarget.size() == 0) {
            throw new BusinessException("目标节点没有批转记录，不能退回！");
        }
        //获取最后一次批转记录
        /*List<ActZzTaskpzrecords> lastTargetActTaskpzrecords = taskpzrecordsService.list(new QueryWrapper<ActZzTaskpzrecords>()
                .eq("PROCESSINSTID", taskEntity.getProcessInstanceId())
                .eq("TASKID", targetActTaskpzrecords.get(0).getTaskid()));*/
        WfProcessTransfer wfProcessTransfer = nearFromTarget.get(0);
        AddCommentCmd addCommentCmd = new AddCommentCmd(nowTaskId, taskEntity.getProcessInstanceId(), this.approveMessage);
        addCommentCmd.execute(commandContext);
        if (this.variables.containsKey("approveUserId") && !"".equals(this.variables.get("approveUserId").toString())) {
            taskEntity.setAssignee(this.variables.get("approveUserId").toString());
            this.variables.remove("approveUserId");
        }
        taskEntity.setVariables(this.variables);
        // 触发任务监听
        taskEntity.fireEvent("completed");
        //删除相关信息
        Object o = deleteActiveTask(commandContext, allFromProcInstId, taskEntity, processDefinitionEntity, wfProcessTransfer);

        //获取目标节点历史任务
        List<HistoricTaskInstance> hiTargetActTask = findHiTargetActTask(commandContext, taskEntity);
        //创建目标节点任务
        ActivityImpl targetActivity = processDefinitionEntity
                .findActivity(targetActId);
        processHistoryTask(commandContext, taskEntity, wfProcessTransfer, targetActivity, processDefinitionEntity, hiTargetActTask);
        
        //添加到批转轨迹
        String parentExecutionId = "";
        String parentParentExecutionId = "";
        if (taskType.equals("parallel")) {//并行
            parentExecutionId = taskEntity.getExecution().getParent().getId();
            parentParentExecutionId = taskEntity.getExecution().getParent().getParent().getId();
        } else if (taskType.equals("sequential")) {//串行
            parentExecutionId = taskEntity.getExecution().getParent().getId();
        } else {
            if (StringUtils.isNotBlank(taskEntity.getExecution().getParentId())) {
                parentExecutionId = taskEntity.getExecution().getParentId();
            }
        }
        //获取办理人
        String toUsers = "";
        List<String> blrSet = new ArrayList<>();//办理人set
        for (HistoricTaskInstance historicTaskInstancesByQueryCriterion : hiTargetActTask) {
            if (!blrSet.contains(historicTaskInstancesByQueryCriterion.getAssignee())) {
                blrSet.add(historicTaskInstancesByQueryCriterion.getAssignee());
            }
        }

        WfProcessTransfer newWfProcessTransfer = new WfProcessTransfer();
        newWfProcessTransfer.setActId(taskEntity.getTaskDefinitionKey());
        newWfProcessTransfer.setExecId(taskEntity.getExecutionId());
        newWfProcessTransfer.setParExecId(parentExecutionId);
        newWfProcessTransfer.setParParExecId(parentParentExecutionId);
        newWfProcessTransfer.setFormUser(taskEntity.getAssignee());
        newWfProcessTransfer.setTaskType(taskType);
        newWfProcessTransfer.setProcInstId(taskEntity.getProcessInstanceId());
        newWfProcessTransfer.setTaskId(taskEntity.getId());
        newWfProcessTransfer.setToActId(targetActId);
        wfProcessTransferService.save(newWfProcessTransfer);
        return o;

    }

    private Object deleteActiveTask(CommandContext commandContext, List<WfProcessTransfer> allFromProcInstId, TaskEntity taskEntity, ProcessDefinitionEntity processDefinitionEntity, WfProcessTransfer lastTargetWfProcessTransfer) {
        List<Map<String, String>> deleteTaskMap = new ArrayList<>();
        //获取流程实例
        String processInstanceId = taskEntity.getProcessInstanceId();

        //根据taskId获取从目标节点流转的最后一次记录
        List<WfProcessTransfer> lastFromTargetTaskId = wfProcessTransferService.getListByProcInstIdAndTaskIdOrderByCreateDateAsc(taskEntity.getProcessInstanceId(), lastTargetWfProcessTransfer.getTaskId());
        //获取从目标节点流转的所有记录
        List<WfProcessTransfer> allFromTargetActId = getAllRecordsFromTargetActId(allFromProcInstId, targetActId, lastFromTargetTaskId.get(0).getCreateDate());
        Set<String> executionIdsNotEqFlowId = new HashSet<>();
        Set<String> collect = new HashSet<>();
        for (WfProcessTransfer wfProcessTransfer : allFromProcInstId) {
            collect.add(wfProcessTransfer.getToActId());
            String taskType = wfProcessTransfer.getTaskType();
            if (taskType.equals("userTask")) {
                if (!wfProcessTransfer.getExecId().equals(processInstanceId)) {
                    executionIdsNotEqFlowId.add(wfProcessTransfer.getExecId());
                }
            } else if (taskType.equals("parallel")) {
                if (!wfProcessTransfer.getParParExecId().equals(processInstanceId)) {
                    executionIdsNotEqFlowId.add(wfProcessTransfer.getParParExecId());
                }
            } else if (taskType.equals("sequential")) {
                if (!wfProcessTransfer.getParExecId().equals(processInstanceId)) {
                    executionIdsNotEqFlowId.add(wfProcessTransfer.getParExecId());
                }
            }
        }

        TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
        List<TaskEntity> tasks = taskEntityManager.findTasksByProcessInstanceId(processInstanceId);
        List<TaskEntity> deleteTasks = new ArrayList<>();

        for (TaskEntity task : tasks) {
            String taskDefinitionKey = task.getTaskDefinitionKey();
            if (collect.contains(taskDefinitionKey)) {
                deleteTasks.add(task);
                Map<String, String> taskMap = new HashMap<>();
                taskMap.put("actId", task.getTaskDefinitionKey());
                taskMap.put("name", task.getName());
                deleteTaskMap.add(taskMap);
            }
        }

        ExecutionEntityManager executionEntityManager = Context.getCommandContext().getExecutionEntityManager();
        VariableInstanceEntityManager variableInstanceEntityManager = Context.getCommandContext().getVariableInstanceEntityManager();

        List<ExecutionEntity> parentExecutionForDelete = new ArrayList<>();
        List<ExecutionEntity> parentParentExecutionForParallel = new ArrayList<>();
        Set<ExecutionEntity> executions = new HashSet<>();
        //只删除任务不删除执行对象的列表
        List<ExecutionEntity> executionsNotDel = new ArrayList<>();
        for (TaskEntity deleteTask : deleteTasks) {
            ActivityImpl activity = processDefinitionEntity
                    .findActivity(deleteTask.getTaskDefinitionKey());
            String taskType = this.getTaskType(activity);
            ExecutionEntity execution = deleteTask.getExecution();
            if (taskType.equals("userTask")) {//删除的任务是单人任务
                //taskEntityManager.deleteTask(taskEntity, deleteReason, false);
                if (!execution.getId().equals(processInstanceId)) {
                    //删除执行对象
                    executions.add(execution);
                    //executionEntityManager.delete(execution);
                } else {
                    taskEntity.setDescription(this.approveAdvice);
                    taskEntityManager.deleteTask(taskEntity, deleteReason, false);
                }
            } else {//多人任务
                List<ExecutionEntity> executionEntitys = executionEntityManager.findChildExecutionsByParentExecutionId(execution.getParentId());
                //删除执行对象
                executions.addAll(executionEntitys);
                //executionEntityManager.delete(execution);
                // 删除任务的原因
                //taskEntityManager.deleteTask(taskEntity,deleteReason , false);
                if (taskType.equals("parallel")) {//并行
                    ExecutionEntity parent = execution.getParent();
                    parentExecutionForDelete.add(parent);
                    ExecutionEntity parentParent = parent.getParent();
                    parentParentExecutionForParallel.add(parentParent);
                } else if (taskType.equals("sequential")) {//串行
                    ExecutionEntity parent = execution.getParent();
                    String parentId = parent.getId();
                    if (!parentId.equals(processInstanceId)) {
                        parentExecutionForDelete.add(parent);
                    }
                }

            }
        }
//批转记录中所有等待中的执行对象
        for (String s : executionIdsNotEqFlowId) {
            ExecutionEntity executionById = executionEntityManager.findExecutionById(s);
            if (executionById != null && !executionById.isActive()) {
                List<ExecutionEntity> childExecutionsByParentExecutionId = executionEntityManager.findChildExecutionsByParentExecutionId(executionById.getId());
                if (childExecutionsByParentExecutionId.isEmpty()) {
                    //说明这个执行对象正在等待 需删除
                    executions.add(executionById);
                }
            }
        }


        for (ExecutionEntity execution : executions) {
            //删除流程变量
            List<VariableInstanceEntity> varLis2 = variableInstanceEntityManager.findVariableInstancesByExecutionId(execution.getId());
            for (VariableInstanceEntity variableInstanceEntity : varLis2) {
                variableInstanceEntityManager.delete(variableInstanceEntity);
            }
            // 根据executionId 获取Task
            Iterator<TaskEntity> localIterator = Context.getCommandContext()
                    .getTaskEntityManager()
                    .findTasksByExecutionId(execution.getId()).iterator();
            while (localIterator.hasNext()) {
                TaskEntity taskEntity2 = (TaskEntity) localIterator.next();
                taskEntity.setDescription(this.approveAdvice);
                // 删除任务的原因
                Context.getCommandContext().getTaskEntityManager()
                        .deleteTask(taskEntity2, deleteReason, false);
            }
            executionEntityManager.delete(execution);
        }
        for (ExecutionEntity executionEntity : parentExecutionForDelete) {
            //删除流程变量
            List<VariableInstanceEntity> varLis2 = variableInstanceEntityManager.findVariableInstancesByExecutionId(executionEntity.getId());
            for (VariableInstanceEntity variableInstanceEntity : varLis2) {
                variableInstanceEntityManager.delete(variableInstanceEntity);
            }
            //删除执行对象
            executionEntityManager.delete(executionEntity);
        }
        for (ExecutionEntity executionEntity : parentParentExecutionForParallel) {
            if (!executionEntity.getId().equals(processInstanceId)) {
                //删除流程变量
                List<VariableInstanceEntity> varLis2 = variableInstanceEntityManager.
                        findVariableInstancesByExecutionId(executionEntity.getId());
                for (VariableInstanceEntity variableInstanceEntity : varLis2) {
                    variableInstanceEntityManager.delete(variableInstanceEntity);
                }
                executionEntityManager.delete(executionEntity);
            }
        }
        return deleteTaskMap;
    }

    /**
     * 递归获取从目标节点批转出的所有记录
     *
     * @param list
     * @param actId
     * @param afterDate
     * @return
     */
    public List<WfProcessTransfer> getAllRecordsFromTargetActId(List<WfProcessTransfer> list, String actId, Date afterDate) {
        List<WfProcessTransfer> resultList = new ArrayList<>();
        List<WfProcessTransfer> afterPizhuanRecordByActIdAndDate = getAfterPizhuanRecordByActIdAndDate(list, actId, afterDate);
        if (afterPizhuanRecordByActIdAndDate.size() > 0) {
            for (WfProcessTransfer taskpzrecords : afterPizhuanRecordByActIdAndDate) {
                resultList.add(taskpzrecords);
                resultList.addAll(getAllRecordsFromTargetActId(list, taskpzrecords.getToActId(), taskpzrecords.getCreateDate()));
            }
        }

        return resultList;
    }

    public List<WfProcessTransfer> getAfterPizhuanRecordByActIdAndDate(List<WfProcessTransfer> list, String actId, Date afterDate) {
        List<WfProcessTransfer> resultList = new ArrayList<>();
        WfProcessTransfer firstAfterDate = null;
        for (WfProcessTransfer wfProcessTransfer : list) {
            if (wfProcessTransfer.getCreateDate().getTime() >= afterDate.getTime()) {
                if (wfProcessTransfer.getActId().equals(actId)) {
                    firstAfterDate = wfProcessTransfer;
                    break;
                }
            }
        }
        if (firstAfterDate != null) {
            for (WfProcessTransfer wfProcessTransfer : list) {
                if (wfProcessTransfer.getTaskId().equals(firstAfterDate.getTaskId())) {
                    resultList.add(wfProcessTransfer);
                }
            }
        }
        return resultList;
    }


    public String getTaskType(ActivityImpl activity) {
        String taskType = activity.getProperty("type").toString();
        if (activity.getProperties().containsKey("multiInstance")) {
            taskType = activity.getProperty("multiInstance").toString();
        }
        return taskType;
    }

    /**
     * 获取目标节点的所有历史任务
     *
     * @param commandContext
     * @param taskEntity
     * @return
     */
    public List<HistoricTaskInstance> findHiTargetActTask(CommandContext commandContext, TaskEntity taskEntity) {
        HistoricTaskInstanceQueryImpl historicTaskInstanceQueryImpl = new HistoricTaskInstanceQueryImpl();
        historicTaskInstanceQueryImpl.taskDefinitionKey(targetActId)
                .processInstanceId(taskEntity.getProcessInstanceId())
                .finished().orderByHistoricTaskInstanceEndTime().desc();


        List<HistoricTaskInstance> historicTaskInstancesByQueryCriteria = commandContext.getHistoricTaskInstanceEntityManager()
                .findHistoricTaskInstancesByQueryCriteria(
                        historicTaskInstanceQueryImpl);
        return historicTaskInstancesByQueryCriteria;
    }

    /**
     * 根据任务历史，创建待办任务.
     *
     * @param commandContext
     * @param taskEntity
     * @param wfProcessTransfer
     */
    public void processHistoryTask(CommandContext commandContext, TaskEntity taskEntity
            , WfProcessTransfer wfProcessTransfer, ActivityImpl targetActivity
            , ProcessDefinitionEntity processDefinitionEntity, List<HistoricTaskInstance> hiTargetActTask) {
        if (wfProcessTransfer.getTaskType().equals("userTask")) {
            rollbackToSingleTaskForCreate(commandContext, hiTargetActTask, wfProcessTransfer, targetActivity, processDefinitionEntity, taskEntity);
        } else {//目标节点是多人任务
            rollbackToMoreTaskForCreate(commandContext, hiTargetActTask, wfProcessTransfer, targetActivity, taskEntity, processDefinitionEntity);

        }

    }
 
 
    /*public List<Map<String, Object>> getPreAct(String nowActivityId, ProcessDefinitionEntity processDefinitionEntity) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        //获取当前节点
        ActivityImpl activity = processDefinitionEntity.findActivity(nowActivityId);
        //获取所有入线
        List<PvmTransition> incomingTransitions = activity.getIncomingTransitions();
        for (PvmTransition incomingTransition : incomingTransitions) {
            //获取入线的开始节点
            PvmActivity source = incomingTransition.getSource();
            Map<String, Object> node = new HashMap<>();
            node.put("activityId", source.getId());
            node.put("name", source.getProperty("name"));
            node.put("type", source.getProperty("type"));
            resultList.add(node);
        }
        return resultList;
    }
    public List<Map<String, Object>> getAllPreAct(String nowActivityId,ProcessDefinitionEntity processDefinitionEntity){
        List<Map<String, Object>> resultList = new ArrayList<>();
        List<Map<String, Object>> prekActs = getPreAct(nowActivityId, processDefinitionEntity);
        for (Map<String, Object> prekAct : prekActs) {
            resultList.add(prekAct);
            nowActivityId = prekAct.get("activityId").toString();
            resultList.addAll(getAllPreAct(nowActivityId,processDefinitionEntity));
        }
        return resultList;
    }*/

    /**
     * 退回到单人任务-创建相关数据
     *
     * @param commandContext
     * @param hiTargetActTask
     * @param lastTargetPzRecord
     * @param targetActivity
     */
    public void rollbackToSingleTaskForCreate(CommandContext commandContext,
                                              List<HistoricTaskInstance> hiTargetActTask,
                                              WfProcessTransfer lastTargetPzRecord,
                                              ActivityImpl targetActivity, ProcessDefinitionEntity processDefinitionEntity, TaskEntity taskEntity) {
        ExecutionEntityManager executionEntityManager = Context
                .getCommandContext().getExecutionEntityManager();
        ExecutionEntity mainExecution = executionEntityManager.findExecutionById(lastTargetPzRecord.getProcInstId());
        HistoricTaskInstance historicTaskInstance = hiTargetActTask.get(0);
        String userId = historicTaskInstance.getAssignee();
        // 创建新任务
        TaskEntity task = TaskEntity.create(new Date());
        Set<Expression> candidateUserIdExpressions = null;
        Set<Expression> candidateGroupIdExpressions = null;
        TaskDefinition taskDefinition = processDefinitionEntity
                .getTaskDefinitions().get(historicTaskInstance.getTaskDefinitionKey());

        if (taskDefinition == null) {
            String message = "cannot find taskDefinition : "
                    + historicTaskInstance.getTaskDefinitionKey();
            throw new IllegalStateException(message);
        }
        if (taskDefinition.getCandidateUserIdExpressions() != null) {
            candidateUserIdExpressions = taskDefinition.getCandidateUserIdExpressions();//策略
        }
        if (taskDefinition.getCandidateUserIdExpressions() != null) {
            candidateGroupIdExpressions = taskDefinition.getCandidateGroupIdExpressions();//岗位
        }
        this.setTaskEntity(task, historicTaskInstance, userId);

        //是否需要创建执行对象
        if (!lastTargetPzRecord.getExecId().equals(lastTargetPzRecord.getProcInstId())) {
            //说明在分支上 需要创建执行对象
            mainExecution.setActive(false);
            ExecutionEntity executionEntity_parent = new ExecutionEntity();
            executionEntity_parent.setParentId(mainExecution.getId());
            executionEntity_parent.setCachedEntityState(6);
            executionEntity_parent.setProcessDefinitionKey(processDefinitionEntity.getKey());
            executionEntity_parent.setProcessInstance(taskEntity.getProcessInstance());
            executionEntity_parent.setProcessDefinitionId(processDefinitionEntity.getId());
            executionEntity_parent.setActivity(targetActivity);
            executionEntity_parent.setActive(true);
            executionEntity_parent.setConcurrent(true);
            executionEntity_parent.setScope(false);
            String id = "obj" + UuidUtil.get32UUID();
            executionEntity_parent.setId(id);
            executionEntityManager.insert(executionEntity_parent);
            // 创建HistoricActivityInstance
            Context.getCommandContext().getHistoryManager().recordActivityStart(executionEntity_parent);
            task.setExecutionId(executionEntity_parent.getId());
            commandContext.getTaskEntityManager().insert(task);
            // 创建HistoricTaskInstance
            Context.getCommandContext().getHistoryManager().recordTaskCreated(task, executionEntity_parent);
            Context.getCommandContext().getHistoryManager().recordTaskId(task);
            // 更新ACT_HI_ACTIVITY里的assignee字段
            Context.getCommandContext().getHistoryManager().recordTaskAssignment(task);
        } else {//说明在主线上 不需要创建执行对象
            task.setExecutionId(mainExecution.getId());
            commandContext.getTaskEntityManager().insert(task);
            mainExecution.setActive(true);
            mainExecution.setActivity(targetActivity);
            // 创建HistoricActivityInstance
            Context.getCommandContext().getHistoryManager().recordActivityStart(mainExecution);
            // 创建HistoricTaskInstance
            Context.getCommandContext().getHistoryManager().recordTaskCreated(task, mainExecution);
            Context.getCommandContext().getHistoryManager().recordTaskId(task);
            // 更新ACT_HI_ACTIVITY里的assignee字段
            Context.getCommandContext().getHistoryManager().recordTaskAssignment(task);
        }
        if (candidateUserIdExpressions != null) {
            for (Expression es : candidateUserIdExpressions) {
                getProcessEngine().getTaskService().addCandidateUser(task.getId(), es.getExpressionText());
            }
        }
        if (candidateGroupIdExpressions != null) {
            for (Expression es : candidateGroupIdExpressions) {
                task.addCandidateGroup(es.getExpressionText());
                getProcessEngine().getTaskService().addCandidateGroup(task.getId(), es.getExpressionText());
            }
        }
        task.fireEvent("create");
    }

    /**
     * 根据历史任务设置任务属性
     *
     * @param task
     * @param historicTaskInstanceEntity
     * @param userId
     */
    public void setTaskEntity(TaskEntity task, HistoricTaskInstance historicTaskInstanceEntity, String userId) {
        task.setProcessDefinitionId(historicTaskInstanceEntity.getProcessDefinitionId());
        task.setAssigneeWithoutCascade(userId);
        task.setParentTaskIdWithoutCascade(historicTaskInstanceEntity.getParentTaskId());
        task.setNameWithoutCascade(historicTaskInstanceEntity.getName());
        task.setTaskDefinitionKey(historicTaskInstanceEntity.getTaskDefinitionKey());
        task.setFormKey(historicTaskInstanceEntity.getFormKey());
        task.setFileId(historicTaskInstanceEntity.getFileId());
        task.setTaskState(this.approveAdvice);
        task.setPriority(historicTaskInstanceEntity.getPriority());
        task.setProcessInstanceId(historicTaskInstanceEntity.getProcessInstanceId());
        //task.setDescriptionWithoutCascade(historicTaskInstanceEntity.getDescription());
        task.setTenantId(historicTaskInstanceEntity.getTenantId());
    }

    /**
     * 退回到多人任务-创建相关数据
     *
     * @param commandContext
     * @param hiTargetActTask
     * @param lastTargetPzRecord
     * @param targetActivity
     */
    public void rollbackToMoreTaskForCreate(CommandContext commandContext,
                                            List<HistoricTaskInstance> hiTargetActTask,
                                            WfProcessTransfer lastTargetPzRecord,
                                            ActivityImpl targetActivity, TaskEntity taskEntity
            , ProcessDefinitionEntity processDefinitionEntity) {
        //获取办理人
        List<String> blrSet = new ArrayList<>();//办理人set
        for (HistoricTaskInstance historicTaskInstancesByQueryCriterion : hiTargetActTask) {
            if (!blrSet.contains(historicTaskInstancesByQueryCriterion.getAssignee())) {
                blrSet.add(historicTaskInstancesByQueryCriterion.getAssignee());
            }
        }
        //获取执行对象管理类
        ExecutionEntityManager executionEntityManager = Context
                .getCommandContext().getExecutionEntityManager();
        ExecutionEntity mainExecution = executionEntityManager.findExecutionById(lastTargetPzRecord.getProcInstId());
        String taskType = lastTargetPzRecord.getTaskType();
        if (taskType.equals("parallel")) {//并行
            mainExecution.setActive(false);
            ExecutionEntity executionEntity_parent = new ExecutionEntity();
            if (!lastTargetPzRecord.getParParExecId().equals(lastTargetPzRecord.getProcInstId())) {
                //说明不在主线上 需创建父级执行对象
                ExecutionEntity executionEntity_parent_parent = new ExecutionEntity();
                executionEntity_parent_parent.setParentId(mainExecution.getId());
                executionEntity_parent_parent.setCachedEntityState(6);
                executionEntity_parent_parent.setProcessDefinitionKey(processDefinitionEntity.getKey());
                executionEntity_parent_parent.setProcessInstance(taskEntity.getProcessInstance());
                executionEntity_parent_parent.setProcessDefinitionId(taskEntity.getProcessDefinitionId());
                executionEntity_parent_parent.setActive(false);
                executionEntity_parent_parent.setConcurrent(true);
                executionEntity_parent_parent.setScope(false);
                String parentParentId = "obj" + UuidUtil.get32UUID();
                executionEntity_parent_parent.setId(parentParentId);
                Context.getCommandContext().getExecutionEntityManager().insert(executionEntity_parent_parent);

                executionEntity_parent.setParentId(executionEntity_parent_parent.getId());
            } else {
                mainExecution.setActivity(targetActivity);
                executionEntity_parent.setParentId(mainExecution.getId());
            }
            executionEntity_parent.setCachedEntityState(6);
            executionEntity_parent.setProcessDefinitionKey(processDefinitionEntity.getKey());
            executionEntity_parent.setProcessInstance(taskEntity.getProcessInstance());
            executionEntity_parent.setProcessDefinitionId(taskEntity.getProcessDefinitionId());
            executionEntity_parent.setActivity(targetActivity);
            executionEntity_parent.setActive(false);
            executionEntity_parent.setConcurrent(false);
            executionEntity_parent.setScope(true);
            String parentId = "obj" + UuidUtil.get32UUID();
            executionEntity_parent.setId(parentId);
            Context.getCommandContext().getExecutionEntityManager().insert(executionEntity_parent);
            // 创建多实例任务
            // 创建多实例任务
            this.createVariable(blrSet.size(), blrSet.size(), executionEntity_parent.getId(), taskEntity.getProcessInstanceId(), "", true);
            int i = 0;
            for (String s : blrSet) {
                ExecutionEntity executionEntity_c = new ExecutionEntity();
                executionEntity_c.setParentId(executionEntity_parent.getId());
                executionEntity_c.setActive(true);
                executionEntity_c.setScope(false);
                executionEntity_c.setConcurrent(true);
                executionEntity_c.setActivity(targetActivity);
                executionEntity_c.setCachedEntityState(7);
                executionEntity_c.setProcessDefinitionKey(processDefinitionEntity.getKey());
                executionEntity_c.setProcessInstance(taskEntity.getProcessInstance());
                executionEntity_c.setProcessDefinitionId(taskEntity.getProcessDefinitionId());
                String id = "obj" + UuidUtil.get32UUID();
                executionEntity_c.setId(id);
                Context.getCommandContext().getExecutionEntityManager().insert(executionEntity_c);
                // 创建HistoricActivityInstance
                Context.getCommandContext().getHistoryManager().recordActivityStart(executionEntity_c);
                TaskEntity task = TaskEntity.create(new Date());
                task.setExecutionId(executionEntity_c.getId());
                this.setTaskEntity(task, hiTargetActTask.get(0), s);
                Context.getCommandContext().getTaskEntityManager().insert(task);
                // 创建HistoricTaskInstance
                Context.getCommandContext().getHistoryManager().recordTaskCreated(task, executionEntity_c);
                Context.getCommandContext().getHistoryManager().recordTaskId(task);
                // 更新ACT_HI_ACTIVITY里的assignee字段
                Context.getCommandContext().getHistoryManager().recordTaskAssignment(task);
                task.fireEvent("create");
                String[] varName_ = {"loopCounter", "processUser"};
                for (String name : varName_) {
                    VariableTypes variableTypes = Context.getProcessEngineConfiguration().getVariableTypes();
                    VariableInstanceEntity variableInstance = this.insertVariableInstanceEntity(name, i, executionEntity_c.getId(), taskEntity.getProcessInstanceId());
                    switch (name) {
                        case "loopCounter":
                            variableInstance.setLongValue(Long.valueOf(i));
                            variableInstance.setTextValue(i + "");
                            break;
                        case "processUser":
                            VariableType newType = variableTypes.findVariableType(s);
                            variableInstance.setType(newType);
                            variableInstance.setLongValue(null);
                            variableInstance.setTextValue(s);
                            break;
                    }
                    Context.getCommandContext().getVariableInstanceEntityManager().insert(variableInstance);
                }
                i++;
            }


        } else if (taskType.equals("sequential")) {//串行
            ExecutionEntity executionEntity = new ExecutionEntity();
            mainExecution.setActive(false);
            if (!lastTargetPzRecord.getParExecId().equals(lastTargetPzRecord.getProcInstId())) {
                //说明不在主线上 需创建父级执行对象
                //创建父级执行对象
                ExecutionEntity executionEntity_parent = new ExecutionEntity();
                executionEntity_parent.setParentId(mainExecution.getId());
                executionEntity_parent.setCachedEntityState(6);
                executionEntity_parent.setProcessDefinitionKey(processDefinitionEntity.getKey());
                executionEntity_parent.setProcessInstance(taskEntity.getProcessInstance());
                executionEntity_parent.setProcessDefinitionId(taskEntity.getProcessDefinitionId());
                executionEntity_parent.setActivity(targetActivity);
                executionEntity_parent.setActive(false);
                executionEntity_parent.setConcurrent(true);
                executionEntity_parent.setScope(false);
                String parentId = "obj" + UuidUtil.get32UUID();
                executionEntity_parent.setId(parentId);
                Context.getCommandContext().getExecutionEntityManager().insert(executionEntity_parent);
                executionEntity.setParentId(executionEntity_parent.getId());
            } else {//说明在主线上
                mainExecution.setActivity(targetActivity);
                executionEntity.setParentId(mainExecution.getId());
            }
            HistoricTaskInstance historicTaskInstance = hiTargetActTask.get(0);
            executionEntity.setCachedEntityState(6);
            executionEntity.setProcessDefinitionKey(processDefinitionEntity.getKey());
            executionEntity.setProcessInstance(taskEntity.getProcessInstance());
            executionEntity.setProcessDefinitionId(taskEntity.getProcessDefinitionId());
            executionEntity.setActivity(targetActivity);
            executionEntity.setActive(true);
            executionEntity.setConcurrent(false);
            executionEntity.setScope(true);
            String id = "obj" + UuidUtil.get32UUID();
            executionEntity.setId(id);
            Context.getCommandContext().getExecutionEntityManager().insert(executionEntity);
            // 创建HistoricActivityInstance
            Context.getCommandContext().getHistoryManager().recordActivityStart(executionEntity);
            TaskEntity task = TaskEntity.create(new Date());
            task.setExecutionId(executionEntity.getId());
            this.setTaskEntity(task, historicTaskInstance, blrSet.get(blrSet.size() - 1));
            Context.getCommandContext().getTaskEntityManager().insert(task);
            // 创建HistoricTaskInstance
            Context.getCommandContext().getHistoryManager().recordTaskCreated(task, executionEntity);
            Context.getCommandContext().getHistoryManager().recordTaskId(task);
            // 更新ACT_HI_ACTIVITY里的assignee字段
            Context.getCommandContext().getHistoryManager().recordTaskAssignment(task);
            task.fireEvent("create");
            this.createVariable(blrSet.size(), 1, executionEntity.getId(), taskEntity.getProcessInstanceId(), blrSet.get(blrSet.size() - 1), false);
        }
    }

    /**
     * <p>Title: 创建变量参数</p>
     * <p>Description: </p>
     *
     * @param size
     * @param activeInstanceSize
     * @param executionEntityId
     * @param processInstanceId
     * @param userId
     * @date 2018年8月31日
     * @author lqx
     */
    public void createVariable(int size, int activeInstanceSize, String executionEntityId, String processInstanceId, String userId, boolean isParallel) {
        List<String> varName = new ArrayList<String>();
        varName.add("nrOfInstances");
        varName.add("nrOfCompletedInstances");
        varName.add("nrOfActiveInstances");
        if (!isParallel) {
            varName.add("loopCounter");
            varName.add("processUser");
        }
        for (String name : varName) {
            VariableTypes variableTypes = Context.getProcessEngineConfiguration().getVariableTypes();
            VariableType newType = variableTypes.findVariableType(size);
            VariableInstanceEntity variableInstance = this.insertVariableInstanceEntity(name, size, executionEntityId, processInstanceId);
            switch (name) {
                case "nrOfInstances":
                    variableInstance.setLongValue(Long.valueOf(size));
                    break;
                case "nrOfCompletedInstances":
                    newType = variableTypes.findVariableType(0);
                    variableInstance.setType(newType);
                    variableInstance.setLongValue(0L);
                    variableInstance.setTextValue("0");
                    break;
                case "nrOfActiveInstances":
                    variableInstance.setLongValue(Long.valueOf(activeInstanceSize));
                    if (!isParallel) {
                        variableInstance.setTextValue(activeInstanceSize + "");
                    }
                    break;
                case "loopCounter":
                    variableInstance.setLongValue(0L);
                    variableInstance.setTextValue("0");
                    break;
                case "processUser":
                    newType = variableTypes.findVariableType(userId);
                    variableInstance.setType(newType);
                    variableInstance.setLongValue(null);
                    variableInstance.setTextValue(userId);
                    break;
            }
            Context.getCommandContext().getVariableInstanceEntityManager().insert(variableInstance);
        }
    }

    private VariableInstanceEntity insertVariableInstanceEntity(String name, Object value, String executionId, String processInstanceId) {
        VariableTypes variableTypes = Context.getProcessEngineConfiguration().getVariableTypes();
        VariableType newType = variableTypes.findVariableType(value);
        VariableInstanceEntity variableInstance = VariableInstanceEntity.create(name, newType, value);
        variableInstance.setExecutionId(executionId);
        variableInstance.setProcessInstanceId(processInstanceId);
        return variableInstance;
    }

    /**
     * 获取流程引擎对象
     *
     * @return
     */
    private ProcessEngine getProcessEngine() {
        return ApplicationContextRegister.getApplicationContext().getBean("processEngine", ProcessEngine.class);
    }
}